//TODO
//make it so you can't stop reading until all have been read
//
//no duplicate authors

var STATE = {
  CREATING: 'c',
  CONTINUING: 'm',
  FINISHING: 'f',
  WAITING: 'w',
  READING: 'r'
};

var UNIQUES = 3;

var state = STATE.WAITING;
var currCorpse;
var id = null;
var myCorpsesCounter = 1;
var leader = false;

var gameStatus; //PLAY or READ
var currentRead;
var leaderReadIndex;
var leaderReadOrder;
var numComplete;

function deployProse() {
	
	
	var t1 = document.getElementById("invisibleInput").value;
	var t2 = document.getElementById("visibleInput").value;
	
	if(!t1 || (state !== STATE.finishing && !t2)) {
		displayError('please enter things into the boxes');
		
		return;
	}
	
	document.getElementById('deployProse').setAttribute('disabled','disabled'); // .removeAttribute('disabled');
	var currCorpseID;
	if(state === STATE.CREATING) {
		nextMode = STATE.CONTINUING;
		var currCorpseID = '_corpse_' + myCorpsesCounter++ + '_' + id;
		currCorpse = {'id':currCorpseID, 'lines': [t1,t2], 'nextMode': STATE.CONTINUING, 'authors': []};
	}
	else if(state === STATE.CONTINUING) {
		currCorpse.nextMode = STATE.FINISHING;
		currCorpse.lines.push(t1);
		currCorpse.lines.push(t2);
	}
		
	else if(state === STATE.FINISHING) {
		currCorpse.nextMode = STATE.READING;
		currCorpse.lines.push(t1);
	}
	currCorpse['owner'] = 'NONE';
	currCorpse['authors'].push(id);
	
	var deltaObj = {};
	
	deltaObj[currCorpse.id] = JSON.stringify(currCorpse);
	stopEditing();
	deltaObj[id] = state;
	gapi.hangout.data.submitDelta(deltaObj);
	
}

function displayError(err) {
	document.getElementById("errorMessage").innerHTML = err;
	setTimeout(function() {
		if(document.getElementById("errorMessage").innerHTML === err)
			document.getElementById("errorMessage").innerHTML = '';
	}, 1000);
}

function setUpEditing(corpse) {
	document.getElementById('deployProse').removeAttribute('disabled');
	currCorpse = corpse;
	if(!currCorpse)
		state = STATE.CREATING;
	else
		state = currCorpse.nextMode;
	document.getElementById('inputBox')
            .style.display = 'block';
	document.getElementById('createButton')
            .style.display = 'none';
	var t1 = document.getElementById("invisibleInput");
	var t2 = document.getElementById("visibleInput");
	var prevText = document.getElementById("previousText");
	
	if(state === STATE.CREATING) {
		t1.value = '';
		t2.value = '';
		t2.style.display = 'block';
		prevText.style.display = 'none';
	}
	else if(state === STATE.CONTINUING) {
		t1.value = '';
		t2.value = '';
		t2.style.display = 'block';
		prevText.innerHTML = corpse.lines[1];
		prevText.style.display = 'block';
	}
		
	else if(state === STATE.FINISHING) {
		t1.value = '';
		t2.style.display = 'none';
		prevText.innerHTML = corpse.lines[3];
		prevText.style.display = 'block';
	}
}

function stopEditing() {
	currCorpse = null;
	state = STATE.WAITING;
	document.getElementById('inputBox')
            .style.display = 'none';
	document.getElementById('createButton')
            .style.display = 'block';
}

function showParticipants() {
  var participants = gapi.hangout.getParticipants();

  var retVal = '<p>Participants: </p><ul>';

  for (var index in participants) {
    var participant = participants[index];

    if (!participant.person) {
      retVal += '<li>A participant not running this app</li>';
    }
    retVal += '<li>' + participant.person.displayName + '-' + participant.id + '-' + participant.person.id + '</li>';
  }

  retVal += '</ul>';

  var div = document.getElementById('participantsDiv');

  div.innerHTML = retVal;
}

function createButtonPressed() {
	//state = STATE.CREATING;
	setUpEditing(null);
	var deltaObj = {};
	deltaObj[id] = state;
	gapi.hangout.data.submitDelta(deltaObj);
}


function init() {
  // When API is ready...                                                
  
      var initHangout = function(eventObj) {
        if (eventObj.isApiReady) {
          document.getElementById('createButton')
            .style.display = 'block';
			//showParticipants();
			id = gapi.hangout.getLocalParticipantId();
			var deltaObj = {};
			state = STATE.WAITING;
			deltaObj[id] = state;
			gapi.hangout.data.submitDelta(deltaObj);
			gapi.hangout.data.submitDelta()
			gapi.hangout.data.onStateChanged.add(updateFunction);
			updateFunction({'state' : gapi.hangout.data.getState()});
			gapi.hangout.onApiReady.remove(initHangout);
        }
      };
	  gapi.hangout.onApiReady.add(initHangout);
}

function readCorpse(corpse) {
	document.getElementById('readingBox')
            .style.display = 'block';
	document.getElementById('gameBox')
            .style.display = 'none';
	document.getElementById('part1Box').innerHTML = corpse.lines[0] + ' ' + corpse.lines[1];
	document.getElementById('part2Box').innerHTML = corpse.lines[2] + ' ' + corpse.lines[3];
	document.getElementById('part3Box').innerHTML = corpse.lines[4];
}

function leaderButtonPressed() {
	gapi.hangout.data.submitDelta({'leader':id});
	console.log(gapi.hangout.data.getState());
}

function nextButtonPressed() {
	leaderReadIndex++;
	if(leaderReadIndex === leaderReadOrder.length - 1)
		document.getElementById('nextButton').setAttribute('disabled','disabled'); // .removeAttribute('disabled');
	document.getElementById('prevButton').removeAttribute('disabled');
	var deltaObj = {'readIndex': leaderReadIndex + ''};
	gapi.hangout.data.submitDelta(deltaObj);
}

function prevButtonPressed() {
	leaderReadIndex--;
	if(leaderReadIndex === 0)
		document.getElementById('prevButton').setAttribute('disabled','disabled'); // .removeAttribute('disabled');
	document.getElementById('nextButton').removeAttribute('disabled');
	var deltaObj = {'readIndex': leaderReadIndex + ''};
	gapi.hangout.data.submitDelta(deltaObj);
}

function gameButtonPressed() {
	if(gameStatus === 'READ' || !gameStatus) {
		//start game
		var deltaObj = {'game' : 'PLAY', 'leader':id};
		var remove = gapi.hangout.data.getKeys();
		remove.splice(remove.indexOf('leader'),1);
		if(remove.indexOf('game') !== -1)
			remove.splice(remove.indexOf('game'),1);
		gapi.hangout.data.submitDelta(deltaObj, remove);
	}
	if(gameStatus === 'PLAY') {
		if(!numComplete) {
			displayError('wait till there is at one complete one geez');
			return;
		}
		//start read
		leaderReadIndex = 0;
		leaderReadOrder = getReadOrder();
		var deltaObj = {'game' : 'READ', 'readIndex':'0', 'readOrder' : JSON.stringify(leaderReadOrder)};
		gapi.hangout.data.submitDelta(deltaObj);
	}
}

function getReadOrder() {
	var list = [];
	var state = gapi.hangout.data.getState();
	var keys = Object.keys(state);
	for(var i = 0; i < keys.length; i++) {
		var val = state[keys[i]];
		if(keys[i].substring(0, ('_corpse_').length) === '_corpse_') {
			//it's a corpse
			var corpse = JSON.parse(val);
			if(corpse.nextMode === STATE.READING)
				list.push(corpse.id);
		}
	}
	return list;
}

function deLeader() {
	leader = false;
	document.getElementById('leaderBox')
				.style.display = 'none';
	document.getElementById('leaderButton')
				.style.display = 'block';
}

function makeMeLeader() { 
	leader = true;
	document.getElementById('leaderBox')
				.style.display = 'block';
	document.getElementById('leaderButton')
				.style.display = 'none';
	if(gameStatus === 'PLAY') {
		beginGame();
	}
	else  if(gameStatus === 'READ') {
		beginRead();
	}
}

function beginGame() {
	currCorpse = null;
	leaderReadOrder = null;
	document.getElementById('readingBox')
            .style.display = 'none';
	document.getElementById('gameBox')
            .style.display = 'block';
	if(leader) {
		document.getElementById('leaderReadingBox')
            .style.display = 'none';
		document.getElementById('leaderGameBox')
				.style.display = 'block';
		document.getElementById('gameButton').value = 'end game';
	}
}

function beginRead() {
	document.getElementById('readingBox')
            .style.display = 'block';
	document.getElementById('gameBox')
            .style.display = 'none';
	if(currentRead) {
		readCorpse(currentRead);
	}	
	if(leader) {
		document.getElementById('leaderReadingBox')
            .style.display = 'block';
		document.getElementById('leaderGameBox')
				.style.display = 'block';
		document.getElementById('gameButton').value = 'start game';
		if(leaderReadIndex === 0)
			document.getElementById('prevButton').setAttribute('disabled','disabled'); // .removeAttribute('disabled');
		else
			document.getElementById('prevButton').removeAttribute('disabled');
		if(leaderReadIndex === leaderReadOrder.length - 1)
			document.getElementById('nextButton').setAttribute('disabled','disabled'); // .removeAttribute('disabled');
		else
			document.getElementById('nextButton').removeAttribute('disabled');
	}
}

function getNameByID(playerID) {
	var p = gapi.hangout.getParticipantById(playerID);
	if(p)
		return p.person.displayName;
	return " well there's really no leader as far as I can tell";
}

var updateFunction = function (event ) {
		//showParticipants();
			
			var deltaObj = {};
			var oldGameStatus = gameStatus;
			var keys = Object.keys(event.state);
			
			if(event.state['game'] === 'READ') {
				var readCorpseIndex = parseInt(event.state['readIndex']);
				leaderReadIndex = readCorpseIndex;
				if(!leaderReadOrder)
					leaderReadOrder = JSON.parse(event.state['readOrder']);
				var readCorpseID = leaderReadOrder[readCorpseIndex];
				if(!currentRead || readCorpseID !== currentRead.id) {
					for(var i = 0; i < keys.length; i++) {
					var val = event.state[keys[i]];
						if(keys[i] === readCorpseID) {
							currentRead = JSON.parse(val);
							readCorpse(currentRead);
							break;
						}
					}
				}
			}
			if(leader) {
				document.getElementById('leaderInfo').innerHTML = 'You are our glorious leader';
				if(event.state['leader'] !== id) {
					deLeader();
				}
			}
			else {
				document.getElementById('leaderInfo').innerHTML = 'leader is ' + getNameByID(event.state['leader']);
				if(event.state['leader'] === id) {
					makeMeLeader();
				}
			}
			if(!event.state['game']) {
				gameStatus = null;
				displayError("waiting for leader to start the game");
			} else {
				gameStatus = event.state['game'];
				if(oldGameStatus !== gameStatus) {
					if(gameStatus === 'PLAY') {
						beginGame();
						stopEditing();
					}
					else if(gameStatus === 'READ'){
						beginRead();
					}
				}
			}
			
			if(gameStatus === 'PLAY') {
				var unclaimed = [];
				var completed = 0, inProgress = 0;
				var oldState = state;
				for(var i = 0; i < keys.length; i++) {
					var val = event.state[keys[i]];
					if(keys[i].substring(0, ('_corpse_').length) === '_corpse_') {
						//it's a corpse
						var corpse = JSON.parse(val);
						if(corpse.nextMode === STATE.READING) {
							completed++;
						}
						else {
							inProgress++;
						}
						if(corpse.owner === id) {
							if(!currCorpse && state === STATE.WAITING) {
								setUpEditing(corpse);
							}
							else if(corpse.id !== currCorpse.id) {
								corpse.owner = 'NONE';
								deltaObj[corpse.id] = JSON.stringify(corpse);
							}
						}
						if(leader) {
							if(corpse.owner === 'NONE' && corpse.nextMode !== STATE.READING)
								unclaimed.push(corpse);
						}
						
						
					}
				}
				for(var i = 0; i < keys.length; i++) {
					if(keys[i].substring(0, ('_corpse_').length) !== '_corpse_') {
						//it's a player id
						var val = event.state[keys[i]];
						if(val === STATE.CREATING) inProgress++;
						if(leader) {
							if(val === STATE.WAITING && unclaimed.length > 0) {
								//iterate over unclaimed looking for match
								var j = unclaimed.length;
								while(j--) {
									var corpse = unclaimed[j];
							
									var conflicting = false;
									for(var k = corpse.authors.length - 1; k >= 0 && k >  corpse.authors.length - UNIQUES; k--) {
										if(corpse.authors[k] === keys[i]) {
											conflicting = true;
											break;
										}
									}
									if(!conflicting) {
										unclaimed.splice(j, 1);
										corpse.owner = keys[i];
										deltaObj[corpse.id] = JSON.stringify(corpse);
										break;
									}
								}
							}
						}
							
					}
				}
				
					
				console.log(JSON.stringify(event.state));
				if(oldState !== state) {
					deltaObj[id] = state;
				}
			}
			
			if(deltaObj !== {}) {
				gapi.hangout.data.submitDelta(deltaObj);
			}
			document.getElementById('infoText').innerHTML = inProgress + ' in progress and ' + completed + ' complete.';
			numComplete = completed;

		};

// Wait for gadget to load.                                                       
gadgets.util.registerOnLoadHandler(init);